### 4.12 `fgets`, `fgets_unlocked`—get character string from a file or stream

Synopsis

         #include <stdio.h>
         char *fgets(char *restrict buf, int n, FILE *restrict fp);

         #define _GNU_SOURCE
         #include <stdio.h>
         char *fgets_unlocked(char *restrict buf, int n, FILE *restrict fp);

         #include <stdio.h>
         char *_fgets_r(struct _reent *ptr, char *restrict buf, int n, FILE *restrict fp);

         #include <stdio.h>
         char *_fgets_unlocked_r(struct _reent *ptr, char *restrict buf, int n, FILE *restrict fp);

Description
Reads at most n-1 characters from fp until a newline is found. The characters including to the newline are stored in buf. The buffer is terminated with a 0.

`fgets_unlocked` is a non-thread-safe version of `fgets`. `fgets_unlocked` may only safely be used within a scope protected by flockfile() (or ftrylockfile()) and funlockfile(). This function may safely be used in a multi-threaded program if and only if they are called while the invoking thread owns the (FILE *) object, as is the case after a successful call to the flockfile() or ftrylockfile() functions. If threads are disabled, then `fgets_unlocked` is equivalent to `fgets`.

The functions `_fgets_r` and `_fgets_unlocked_r` are simply reentrant versions that are passed the additional reentrant structure pointer argument: ptr.

Returns
`fgets` returns the buffer passed to it, with the data filled in. If end of file occurs with some data already accumulated, the data is returned with no other indication. If no data are read, NULL is returned instead.

Portability
`fgets` should replace all uses of `gets`. Note however that `fgets` returns all of the data, while `gets` removes the trailing newline (with no indication that it has done so.)

`fgets_unlocked` is a GNU extension.

Supporting OS subroutines required: `close`, `fstat`, `isatty`, `lseek`, `read`, `sbrk`, `write`.